import re

from merchant.billing.validateable import Validateable
from merchant.billing.expiry import ExpiryDate
from merchant.billing.card_companies import CARD_COMPANIES

class CreditCard(Validateable):
    
    def __init__(self, number, month, year, card_type, name, verification_value=None):
        self.number = re.sub('[^\d]', '', str(number))
        self.month = int(month)
        self.year = int(year)
        self.card_type = card_type.lower()
        self.name = name
        self.verification_value = verification_value
        Validateable.__init__(self)

    def __repr__(self):
        return u"%s X-%s (%s)" % (self.card_type, self.last_numbers(), self.expiry_date)
        
    def mask(self):
        return u"XXXX-XXXX-XXXX-%s" % self.last_numbers()
        
    def last_numbers(self):
        return unicode(self.number)[-4:]
    
    @property
    def expiry_date(self):
        return ExpiryDate(self.month, self.year)
        
    def is_expired(self):
        return self.expiry_date.is_expired()
        
    def is_valid_number(self):
        try:
            pattern = CARD_COMPANIES[self.card_type]
            return bool(re.match(pattern, self.number))
        except KeyError:
            return False
        
    def validate(self):
        errors = []
        if self.is_expired():
            errors.append({'expiry_date': u"Card is expired."})
        if not self.is_valid_number():
            errors.append({'number': u'Invalid %s number.' % self.card_type})
        return errors
